<?php
namespace App\Common\Lib\Com\Timer;

use App\Common as com;
use App\Common\Lib\Com\Timer\TimeWheelPools as thisTimeWheelPools;

class TimeWheelPools extends com\Lib\LibBase {

	private array $config = [
		'timeWheels' => [ // 时间轮
			// <1秒
			0 => [
				// 'scanIntervalMs' => 1, // 扫描间隔，单位：毫秒
				'maxTimeDiffMs' => 1000, // 最大的时间，单位：毫秒。[null]无穷大
			],
			// <1分钟
			1 => [
				// 'scanIntervalMs' => 1000, // 扫描间隔，单位：毫秒
				'maxTimeDiffMs' => 1000 * 60, // 最大的时间，单位：毫秒。[null]无穷大
			],
			// <1小时
			2 => [
				// 'scanIntervalMs' => 1000 * 60, // 扫描间隔，单位：毫秒
				'maxTimeDiffMs' => 1000 * 3600, // 最大的时间，单位：毫秒。[null]无穷大
			],
			// <1天
			3 => [
				// 'scanIntervalMs' => 1000 * 60, // 扫描间隔，单位：毫秒
				'maxTimeDiffMs' => 1000 * 3600 * 24, // 最大的时间，单位：毫秒。[null]无穷大
			],
			// >1天
			4 => [
				// 'scanIntervalMs' => 1000 * 60, // 扫描间隔，单位：毫秒
				'maxTimeDiffMs' => null, // 最大的时间，单位：毫秒。[null]无穷大
			],
		]
	];



	private array $taskPools = [];

	private int $taskPoolsMaxId = 0;

	/**
	 * @var thisTimeWheelPools\Item[]
	 */
	private array $timeWheelPools;

	public function __construct( array|null $poolsConfig = null ) {
		if( $poolsConfig !== null ){
			$this->config = $poolsConfig;
		}
		//
		$this->initTimePools();
		//
	    parent::__construct();
	}

	private function initTimePools(){
		$this->timeWheelPools = [];
		foreach( $this->config['timeWheels'] as $timeWheel ){
			$this->timeWheelPools[] = thisTimeWheelPools\Item::make();
		}
	}

	/**
	 * @param int $timeMs
	 * @return int
	 * @throws com\Lib\Err\BaseException\Throw_
	 * @throws com\Lib\Err\Exception
	 */
	private function getMatchTimeWheelId( int $timeMs ):int {
		foreach( $this->config['timeWheels'] as $timeWheelKey => $timeWheel ){
			if( $timeMs < $timeWheel['maxTimeDiffMs'] || $timeWheel['maxTimeDiffMs'] === null ){
				return $timeWheelKey;
			}
		}
		//
		throw com\Lib\Err\Exception::makeOfNew( '', com\Lib\Err\Code::$sysAssertError );
	}

	/**
	 * @param \Closure $taskFn
	 * @param int $timeMs
	 * @return int 任务id
	 * @throws com\Lib\Err\BaseException\Throw_
	 * @throws com\Lib\Err\Exception
	 */
	public function push( \Closure &$taskFn, int $timeMs ):int {
		// 放入任务池
		$taskId = $this->taskPoolsMaxId++;
		$this->taskPools[ $taskId ] = $taskFn;
		// 检查适合的时间轮
		$useTimeWheelId = $this->getMatchTimeWheelId( $timeMs );
		// 推入时间轮
		$this->timeWheelPools[ $useTimeWheelId ]->push( $taskId, $taskFn, $timeMs );
		//
		return $taskId;
	}

	public function rm(  ) {

	}

	public function loop(  ) {
		while( true ){
			$this->loopOne();
			// 休眠1毫秒
			\Swoole\Coroutine::sleep( 1 );
		}
	}

	public function loopOne(  ) {

	}

}
